﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace Alone {
    public class CameraHandler : GameComponent {
        protected Vector3 _position;
        protected Vector3 _lookAt;
        protected Matrix _viewMatrix;
        protected Matrix _projectionMatrix;
        private Vector3 _thirdPersonView;



        /// <summary>
        /// Initializes a new instance of the <see cref="CameraHandler"/> class.
        /// </summary>
        /// <param name="game">Game, that the game component should be attached to.</param>
        public CameraHandler(Game game) : base(game) {

            _position = new Vector3(0, -220f, -20f);
            _lookAt = Vector3.Zero;
            _thirdPersonView = new Vector3(0, 20f, -50f);

            _viewMatrix = Matrix.CreateLookAt(this.Position, this.LookAt, Vector3.Up);
            game.Components.Add(this);
            game.Services.AddService(typeof(CameraHandler), this);
        }

        /// <summary>
        /// Gets or sets the position.
        /// </summary>
        /// <value>The position.</value>
        public Vector3 Position {
            get { return this._position; }
            set {
                this._position = value;
                this._viewMatrix = Matrix.CreateLookAt(value, this.LookAt, Vector3.Up);
            }
        }
        /// <summary>
        /// Gets or sets the look at vector.
        /// </summary>
        /// <value>The look at vector.</value>
        public Vector3 LookAt {
            get { return this._lookAt; }
            set {
                this._lookAt = value;
                this._viewMatrix = Matrix.CreateLookAt(this.Position, value, Vector3.Up);
            }
        }
        /// <summary>
        /// Gets or sets the view matrix.
        /// </summary>
        /// <value>The view matrix.</value>
        public Matrix ViewMatrix {
            get { return this._viewMatrix; }
            set { this._viewMatrix = value; }
        }
        /// <summary>
        /// Gets the projection matrix.
        /// </summary>
        /// <value>The projection matrix.</value>
        public Matrix ProjectionMatrix {
            get { return this._projectionMatrix; }
            set { this._projectionMatrix = value; }
        }

        /// <summary>
        /// Gets the third person view.
        /// </summary>
        /// <value>The third person view.</value>
        public Vector3 ThirdPersonView {
            get { return _thirdPersonView; }
        }

        /// <summary>
        /// Updates the third person camera.
        /// </summary>
        /// <param name="yPosAvatar">The avatars y positionr.</param>
        /// <param name="avatarPosition">The avatar position.</param>
        public void UpdateCameraThirdPerson(float yPosAvatar, Vector3 avatarPosition) {
            Matrix rotationMatrix = Matrix.CreateRotationY(yPosAvatar);

            Vector3 transformedReference =
                Vector3.Transform(this._thirdPersonView, rotationMatrix);

            Vector3 cameraPosition = transformedReference + avatarPosition;

            this._viewMatrix = Matrix.CreateLookAt(cameraPosition, avatarPosition,
                new Vector3(0.0f, 1.0f, 0.0f));
        }
    }
}
